﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyGame.Models
{
    /// <summary>
    /// 游戏类
    /// </summary>
    class Game
    {
        private const int Cols = 15;//列数
        private const int Rows = 15;//行数
        private bool NextIsBlack;
        /// <summary>
        /// 所有的块类的集合
        /// </summary>
        private List<Block> Blocks { get; set; }

        /// <summary>
        /// 初始化
        /// </summary>
        public Game()
        {
            NextIsBlack = true;
            //初始化集合
            Blocks = new List<Block>();
            for (int i = 0; i < Rows; i++)
            {
                for (int j = 0; j < Cols; j++)
                {
                    Blocks.Add(new Block(i, j));
                }
            }
        }

        /// <summary>
        /// 绘制当前游戏的场景
        /// </summary>
        /// <param name="g">绘图句柄</param>
        /// <param name="size">游戏区域尺寸</param>
        public void Draw(Graphics g, Size size)
        {
            //画背景
            Rectangle rec = new Rectangle(new Point(0, 0), size);
            g.DrawImage(Properties.Resources.bg, rec);

            //画格子
            float unitColWidth = size.Width / (Cols + 1);
            float unitRowHeigh = size.Height / (Rows + 1);
            //横线
            for (int i = 0; i < Rows; i++)
            {
                PointF pointStart = new PointF(unitColWidth, (i + 1) * unitRowHeigh);
                PointF pointEnd = new PointF(unitColWidth * Cols, (i + 1) * unitRowHeigh);
                g.DrawLine(new Pen(Color.Black), pointStart, pointEnd);
            }
            //竖线
            for (int i = 0; i < Cols; i++)
            {
                PointF pointStart = new PointF((i + 1) * unitColWidth, unitRowHeigh);
                PointF pointEnd = new PointF((i + 1) * unitColWidth, unitRowHeigh * Rows);
                g.DrawLine(new Pen(Color.Black), pointStart, pointEnd);
            }

            //画棋子
            foreach (var block in Blocks)
            {
                block.Draw(g, new Rectangle
                {
                    Size = new Size((int)unitColWidth, (int)unitRowHeigh),
                    Location = new Point((int)((block.Point.Y + 0.5) * unitColWidth), (int)((block.Point.X + 0.5) * unitRowHeigh)),
                });
            }
        }
        /// <summary>
        /// 处理鼠标点击事件
        /// </summary>
        /// <param name="point"></param>
        /// <param name="size"></param>
        public Block MouseDown(Point point, Size size)
        {
            //当前block的长方形
            float unitColWidth = size.Width / (Cols + 1);
            float unitRowHeigh = size.Height / (Rows + 1);
            foreach (var block in Blocks)
            {
                Rectangle rec = new Rectangle
                {
                    Size = new Size((int)unitColWidth, (int)unitRowHeigh),
                    Location = new Point((int)((block.Point.Y + 0.5) * unitColWidth), (int)((block.Point.X + 0.5) * unitRowHeigh)),
                };

                if (rec.Contains(point))
                {
                    //point这个点在rec这个矩形里
                    if (block.Status == BlockStatus.Blank)
                    {
                        //只处理空白格子
                        block.MouseDown(NextIsBlack);
                        //切换黑白
                        NextIsBlack = !NextIsBlack;
                        //返回当前block
                        return block;
                    }
                    break;
                }
            }
            return null;   //没有点击成功
        }
        /// <summary>
        /// 判断游戏是否结束
        /// </summary>
        /// <param name="block">引发游戏状态改变的那个block</param>
        /// <returns>游戏是否结束，true为结束</returns>
        public bool IsGameOver(Block block)
        {
            var IsStatus = block.Status;//状态
            int x = block.Point.X;//行
            int y = block.Point.Y;//列
            int downNum = 0;
            int rightNum = 0;
            int upNum = 0;
            int leftNum = 0;

            //横向判断
            for (int i = 0; i < 6; i++)
            {
                var nextrightPoint = new Point(x, y + i);
                int nextrightNum = x * Cols + y + i;
                Block bolck1 = Blocks[nextrightNum];

                if (bolck1.Status != IsStatus)
                {
                    rightNum = i;
                    break;
                }
                //跨行处理
                if (y + i == Cols - 1)
                {
                    rightNum = i + 1;
                    break;
                }
            }
            for (int i = 0; i < 7 - rightNum; i++)
            {
                var nextleftPoint = new Point(x, y - i);
                int nextleftNum = x * Cols + y - i;
                Block block2 = Blocks[nextleftNum];

                if (block2.Status != IsStatus)
                {
                    leftNum = i;
                    break;
                }
                //跨行处理
                if (y == i)
                {
                    leftNum = i + 1;
                    break;
                }
            }

            if (rightNum + leftNum >= 6)
            {
                return true;
            }

            //纵向判断
            for (int i = 0; i < 6; i++)
            {
                var nextdownPoint = new Point(x + i, y);
                int nextdownNum = (x + i) * Rows + y;
                Block block3 = Blocks[nextdownNum];

                if (block3.Status != IsStatus)
                {
                    downNum = i;
                    break;
                }

                //防止加到最后一行继续加，超出范围
                if (x + i == Rows - 1)
                {
                    downNum = i + 1;
                    break;
                }
            }

            for (int i = 0; i < 7 - downNum; i++)
            {
                var nextupPoint = new Point(x - i, y);
                int nextupNum = (x - i) * Rows + y;
                Block block4 = Blocks[nextupNum];

                if (block4.Status != IsStatus)
                {
                    upNum = i;
                    break;
                }

                //防止列减到第一行，导致nextupNum小于0
                if (i == x)
                {
                    upNum = i + 1;
                    break;
                }
            }

            if (downNum + upNum >= 6)
            {
                return true;
            }

            //主对角线判断
            for (int i = 0; i < 6; i++)
            {
                var nextdownPoint = new Point(x + i, y + i);
                int nextdownNum = (x + i) * Rows + y + i;
                Block block3 = Blocks[nextdownNum];

                if (block3.Status != IsStatus)
                {
                    downNum = i;
                    break;
                }
                //防止超出列的范围，导致nextdownNum超出范围
                if (x + 1 == Cols - 1)
                {
                    downNum = i + 1;
                    break;
                }

                //行加到最后一行会存在跨行五子的问题
                if (y + i == Rows - 1)
                {
                    downNum = i + 1;
                    break;
                }
            }

            for (int i = 0; i < 7 - downNum; i++)
            {
                var nextupPoint = new Point(x - i, y + i);
                int nextupNum = (x - i) * Rows + y - i;
                Block block4 = Blocks[nextupNum];

                if (block4.Status != IsStatus)
                {
                    upNum = i;
                    break;
                }

                //防止列减到第一行，导致nextupNum小于0
                if (i == x)
                {
                    upNum = i + 1;
                    break;
                }

                //跨行处理
                if (i == y)
                {
                    upNum = i + 1;
                    break;
                }
            }

            if (downNum + upNum >= 6)
            {
                return true;
            }

            //次对角线判断
            for (int i = 0; i < 6; i++)
            {
                var nextdownPoint = new Point(x + i, y - i);
                int nextdownNum = (x + i) * Cols + y - i;
                Block block3 = Blocks[nextdownNum];

                if (block3.Status != IsStatus)
                {
                    downNum = i;
                    break;
                }

                //防止超出列的范围，导致nextdownNum超出范围
                if (x + i == Cols - 1)
                {
                    downNum = i + 1;
                    break;
                }

                //跨行处理
                if (y == i)
                {
                    downNum = i + 1;
                    break;
                }
            }

            for (int i = 0; i < 7 - downNum; i++)
            {
                var nextupPoint = new Point(x - i, y + i);
                int nextupNum = (x - i) * Cols + y + i;
                Block block4 = Blocks[nextupNum];

                if (block4.Status != IsStatus)
                {
                    upNum = i;
                    break;
                }

                //如果减到第一行了，就不能再继续减了，要直接输出的值
                if (i == x)
                {
                    upNum = i + 1;
                    break;
                }

                //行加到最后一行会存在跨行五子问题
                if (y + i == Rows - 1)
                {
                    upNum = i + 1;
                    break;
                }
            }
            if (downNum + upNum >= 6)
                return true;
            else 
                return false;
        }

    }
}
